//
//  ZLImageExtension.swift
//  ZLExtension
//
//  Created by 赵振磊 on 2024/11/15.
//

import UIKit
import Photos

public func ZZImage(_ name: String?) -> UIImage? {
    if name == nil {
        return nil
    }
    return UIImage(named: name!)
}

/// 创建相关
public extension UIImage {
    /// 根据颜色创建图片
    /// - Parameters:
    ///   - color: 颜色
    ///   - size: 尺寸
    /// - Returns: UIImage
    class func zl_image(color: UIColor, size: CGSize = CGSize(width: 100, height: 100)) -> UIImage {
        let renderer = UIGraphicsImageRenderer(size: size)
        return renderer.image { context in
            color.setFill()
            context.fill(CGRect(origin: .zero, size: size))
        }
    }
    /// 创建渐变色图片
    /// - Parameters:
    ///   - colors: 色值
    ///   - size: 尺寸
    ///   - startPoint: 开始位置
    ///   - endPoint: 结束位置
    static func zl_gradientImage(colors: [UIColor],
                                 size: CGSize = CGSizeMake(10, 10),
                                 locations: [Double] = [],
                                 startPoint: CGPoint = CGPoint(x: 0, y: 0),
                                 endPoint: CGPoint = CGPoint(x: 1, y: 0)) -> UIImage? {
        var autoLocaltions = locations
        if autoLocaltions.count == 0 {
            let values = Array(stride(from: 0.0, through: 1.0, by: 1.0 / Double(colors.count - 1)))
            autoLocaltions = values
        }
        let gradientLayer = CAGradientLayer()
        gradientLayer.frame = CGRect(origin: .zero, size: size)
        gradientLayer.colors = colors.map { $0.cgColor }
        gradientLayer.startPoint = startPoint
        gradientLayer.endPoint = endPoint
        gradientLayer.locations = autoLocaltions.map { NSNumber(value: $0) }
        
        UIGraphicsBeginImageContextWithOptions(size, false, 0)
        defer { UIGraphicsEndImageContext() }
        
        if let context = UIGraphicsGetCurrentContext() {
            gradientLayer.render(in: context)
            let image = UIGraphicsGetImageFromCurrentImageContext()
            return image
        }
        
        return nil
    }
    
    /// 重绘图片颜色
    /// - Parameter color: 颜色
    func zl_recolor(to color: UIColor) -> UIImage? {
        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
        guard let context = UIGraphicsGetCurrentContext(), let cgImage = self.cgImage else { return nil }
        let rect = CGRect(origin: .zero, size: self.size)
        context.translateBy(x: 0, y: rect.height)
        context.scaleBy(x: 1.0, y: -1.0)
        context.clip(to: rect, mask: cgImage)
        color.setFill()
        context.fill(rect)
        let coloredImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return coloredImage
    }
}

/// 保存相关
public extension UIImage {
    
    /// 保存图片到相册
    /// - Parameters:
    ///   - name: 名字
    ///   - completion: 完成回调
    func zl_saveToAlbum(name: String, completion: @escaping (Bool, Error?) -> Void) {
        guard let data = self.jpegData(compressionQuality: 0.8) else {
            completion(false, NSError(domain: "com.zzl.extension", code: 0, userInfo: [NSLocalizedDescriptionKey: "图片数据为空"]))
            return
        }
        // 请求相册权限
        PHPhotoLibrary.requestAuthorization { status in
            switch status {
            case .authorized, .limited:
                // 创建一个保存图片的请求
                PHPhotoLibrary.shared().performChanges({
                    // 创建保存图片的请求
                    PHAssetCreationRequest.forAsset().addResource(with: .photo, data: data, options: nil)
                }) { success, error in
                    DispatchQueue.main.async {
                        if success {
                            completion(true, nil)
                        } else {
                            completion(false, error)
                        }
                    }
                }
            case .denied, .restricted:
                DispatchQueue.main.async {
                    completion(false, NSError(domain: "com.zzl.extension", code: 0, userInfo: [NSLocalizedDescriptionKey: "无法访问相册，权限被拒绝"]))
                }
            case .notDetermined:
                // 如果权限未确定，再次请求
                PHPhotoLibrary.requestAuthorization { status in
                    if status == .authorized {
                        self.zl_saveToAlbum(name: name, completion: completion)
                    } else {
                        DispatchQueue.main.async {
                            completion(false, NSError(domain: "com.zzl.extension", code: 0, userInfo: [NSLocalizedDescriptionKey: "无法访问相册，权限被拒绝"]))
                        }
                    }
                }
            @unknown default:
                DispatchQueue.main.async {
                    completion(false, NSError(domain: "com.zzl.extension", code: 0, userInfo: [NSLocalizedDescriptionKey: "未知错误"]))
                }
            }
        }
    }
}

/// 工具
public extension UIImage {
    /// 根据高度获取对应尺寸宽度
    /// - Parameter height: 目标高度
    /// - Returns: 对应比例宽度
    func zl_ratioWidth(height: CGFloat) -> CGFloat {
        if height <= 0 {
            return 0
        }
        return height / self.size.height * self.size.width
    }
    /// 根据高度获取对应尺寸宽度
    /// - Parameter height: 目标高度
    /// - Returns: 对应比例宽度
    func zl_ratioHeight(width: CGFloat) -> CGFloat {
        if width <= 0 {
            return 0
        }
        return width / self.size.width * self.size.height
    }
    /// 宽高比
    func zl_aspectRatio() -> CGFloat {
        return self.size.width / self.size.height
    }
    func zl_width() -> CGFloat {
        return self.size.width
    }
    func zl_height() -> CGFloat {
        return self.size.height
    }
    /// 压缩图片到指定k
    /// - Parameter image: 需要压缩的图片
    /// - Returns: 压缩后的图片数据
    func zl_data(size: Int = 100) -> Data {
        let maxFileSize = size * 1024
        var compression: CGFloat = 1.0
        var imageData = self.jpegData(compressionQuality: compression)
        
        while let data = imageData, data.count > maxFileSize && compression > 0 {
            compression -= 0.1
            imageData = self.jpegData(compressionQuality: compression)
        }
        
        return imageData ?? Data()
    }
    /// 判断是否相等(像素级)
    func zl_equalPixel(image: UIImage?) -> Bool {
        // 如果是同一对象，直接返回 true
        if self === image {
            return true
        }
        
        // 如果尺寸不一样，直接返回 false
        if self.size != image?.size {
            return false
        }
        
        // 开始比对像素
        guard let data1 = self.cgImage?.dataProvider?.data,
              let data2 = image?.cgImage?.dataProvider?.data else {
            return false
        }
        
        let length1 = CFDataGetLength(data1)
        let length2 = CFDataGetLength(data2)
        if length1 != length2 {
            return false
        }
        
        // 逐字节比较
        return CFDataGetBytePtr(data1)?.withMemoryRebound(to: UInt8.self, capacity: length1, { bytes1 in
            CFDataGetBytePtr(data2)?.withMemoryRebound(to: UInt8.self, capacity: length2, { bytes2 in
                memcmp(bytes1, bytes2, length1) == 0
            }) ?? false
        }) ?? false
    }
}

/// 获取
public extension UIImage {
    class func zl_bundleImg(_ imageName: String, bundleClass: AnyClass?, bundleName: String? = nil) -> UIImage {
        if bundleClass == nil {
            return UIImage(named: imageName) ?? UIImage()
        }
        let bundle = Bundle(for: bundleClass!.self)
        let bname = bundleName?.count == 0 ? String(describing: bundleClass.self) : bundleName
        guard let imgBundlePath = bundle.path(forResource: bname, ofType: "bundle") else {
            return UIImage()
        }
        guard let imgBundle = Bundle(path: imgBundlePath) else {
            return UIImage()
        }
        let image = UIImage(named: imageName, in: imgBundle, compatibleWith: nil)
        return image ?? UIImage()
    }
}
